<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2019/11/19 0019
 * Time: 17:55
 */

namespace app\api\library;

use app\admin\service\Lonlat;
use app\admin\service\User;
use EasyWeChat\Factory;
use EasyWeChat\Kernel\Contracts\EventHandlerInterface;
use EasyWeChat\Kernel\Messages\Image;
use EasyWeChat\Kernel\Messages\Text;
use fast\Random;
use think\Config;
use think\Db;
use think\Exception;

class WechatHandle implements EventHandlerInterface
{

    protected $user;
    protected $openid;
    protected $app;
    protected $wechatUser;
    const EXPIRETIME = 30 * 24 *3600;

    protected $msg =
"1、为了大家安全健康，请认真填写真实防疫信息，防疫统计系统将准确统计所在城市，防止误报，请允许公众号使用地理位置！
2、一个微信只能填报一人防疫信息！
3、防疫信息如有变化请每日及时更新。
抗击疫情、共渡时艰！

→ 校内工作人员 <a href='https://yqsb.qau.edu.cn/index/oside/index'> ☛点击此处☚ </a>  填写上报表单。

→ 学生 <a href='https://yqsb.qau.edu.cn/index/report'> ☛点击此处☚ </a>  填写上报表单。
";

    public function __construct()
    {
        $this -> app = Factory::officialAccount(Config::get('wechatConfig'));
    }

    public function handle($message = null)
    {
        $this -> wechatUser = $this -> app -> user->get($message['FromUserName']);
        $this -> openid = $this -> wechatUser['openid'];
        $user = User::getByOpenid($this->openid);
        $extend = [
            'openid'    => $this -> openid,
            'headimgurl'    => $this -> wechatUser['headimgurl'],
            'sex'       => $this -> wechatUser['sex'],
            'city'      => $this -> wechatUser['city'],
            'province'  => $this -> wechatUser['province'],
            'country'    => $this -> wechatUser['country'],
            'is_sub'    => $this -> wechatUser['subscribe']
        ];
        $this -> user = $user ?? self::addUser($this -> wechatUser['nickname'],$extend);

        switch ($message['MsgType']) {
            case 'event':
//                return new Text(serialize($this -> user));
                return $this -> eventHandle($message);
                break;
            case 'text':
                return $this -> textHandle($message);
                break;
            case 'image':
                return '收到图片消息';
                break;
            case 'voice':
                return '收到语音消息';
                break;
            case 'video':
                return '收到视频消息';
                break;
            case 'location':
//                $this -> locationHandle($message);
                break;
            case 'link':
                return '收到链接消息';
                break;
            case 'file':
                return '收到文件消息';
            default:
                return '收到其它消息';
                break;
        }
    }

    protected function locationHandle($message){

//        file_put_contents('location.txt','s');


        $content = file_get_contents('http://api.map.baidu.com/geocoder?location='.$message['Latitude'].','.$message['Longitude'].'&output=json&key=28bcdd84fae25699606ffad27f8da77b');



        $address = json_decode($content,true);
        //return new Text($address['result']['addressComponent']['district']);
        $data = [
            'uid'       => $this -> user -> id,
            'openid'    => $this -> openid,
            'latitude'  => $message['Latitude'],
            'longitude' => $message['Longitude'],
            'precision' => $message['Precision']
        ];

        if($address['status'] == 'OK'){
            $data['formatted_address'] = $address['result']['formatted_address'];
            $data['city'] = $address['result']['addressComponent']['city'];
            $data['province'] = $address['result']['addressComponent']['province'];
            $data['district'] = $address['result']['addressComponent']['district'];
            $data['street'] = $address['result']['addressComponent']['street'];
        }

//        return new Text(json_encode($data));

        (new Lonlat) -> save($data);
        //return new Text(json_encode($data));
    }

    protected function textHandle($message){
        $content = $message['Content'];
        return new Text($this -> msg);
        $imageInfo = $this -> app->qrcode->forever($content);
        $path = $_SERVER['DOCUMENT_ROOT'] . DIRECTORY_SEPARATOR . "assets" . DIRECTORY_SEPARATOR . "users" . DIRECTORY_SEPARATOR . ($this -> user -> id) . DIRECTORY_SEPARATOR;
        if (!is_dir($path)) {
            @mkdir($path, 0777, 1);
        }
        $filename = $path . $content."_qr.jpg";

        $local_file = fopen($filename, 'w');
        $url = $this -> app->qrcode->url($imageInfo["ticket"]);
        $content = file_get_contents($url); // 得到二进制图片内容
        if (false !== $local_file) {
            if (false !== fwrite($local_file, $content)) {
                fclose($local_file);
            }
        }



        return $content;
    }



    /**
     *  post提交数据
     * @param  string $url 请求Url
     * @param  array $datas 提交的数据
     * @return url响应返回的html
     */
    public function sendPost($url, $datas) {
        $temps = array();
        foreach ($datas as $key => $value) {
            $temps[] = sprintf('%s=%s', $key, $value);
        }
        $post_data = implode('&', $temps);
        $url_info = parse_url($url);
        if(empty($url_info['port']))
        {
            $url_info['port']=80;
        }
        $httpheader = "POST " . $url_info['path'] . " HTTP/1.0\r\n";
        $httpheader.= "Host:" . $url_info['host'] . "\r\n";
        $httpheader.= "Content-Type:application/x-www-form-urlencoded\r\n";
        $httpheader.= "Content-Length:" . strlen($post_data) . "\r\n";
        $httpheader.= "Connection:close\r\n\r\n";
        $httpheader.= $post_data;
        $fd = fsockopen($url_info['host'], $url_info['port']);
        fwrite($fd, $httpheader);
        $gets = "";
        $headerFlag = true;
        while (!feof($fd)) {
            if (($header = @fgets($fd)) && ($header == "\r\n" || $header == "\n")) {
                break;
            }
        }
        while (!feof($fd)) {
            $gets.= fread($fd, 128);
        }
        fclose($fd);

        return $gets;
    }

    /**
     * 电商Sign签名生成
     * @param data 内容
     * @param appkey Appkey
     * @return DataSign签名
     */
    public function encrypt($data, $appkey) {
        return urlencode(base64_encode(md5($data.$appkey)));
    }

    protected function eventHandle($message){
        $event = $message['Event'];
        if ($event == 'subscribe') {
            return $this -> subscribe($message);
        } elseif ($event == 'CLICK') {
            if ($message['EventKey'] == 'SCHB') {//生成海报
                if ($this-> user -> poster_media_id && $this -> user -> poster_expire_time - time() > 0) {
                    return new Image($this-> user -> poster_media_id);
                }
                $imageInfo = $this -> app->qrcode->temporary($this -> user -> id,30 * 24 * 3600);
                $path = $_SERVER['DOCUMENT_ROOT'] . DIRECTORY_SEPARATOR . "assets" . DIRECTORY_SEPARATOR . "users" . DIRECTORY_SEPARATOR . ($this -> user -> id) . DIRECTORY_SEPARATOR;
                if (!is_dir($path)) {
                    @mkdir($path, 0777, 1);
                }
                $filename = $path . "_qr.jpg";

                $local_file = fopen($filename, 'w');
                $url = $this -> app->qrcode->url($imageInfo["ticket"]);
                $content = file_get_contents($url); // 得到二进制图片内容
                if (false !== $local_file) {
                    if (false !== fwrite($local_file, $content)) {
                        fclose($local_file);
                    }
                }
                $bg = $_SERVER['DOCUMENT_ROOT'] . DIRECTORY_SEPARATOR . "bg.jpg";
                $target_file = $path . "poster.jpg";
                mergeImage($bg, $filename, $target_file, array('left' => 110, 'top' => 380, 'width' => 123, 'height' => 123));

                //保存头像
                $filename = $path . "avatar.jpg";
                $imgAvatar = downloadImageFromWeiXin($this -> wechatUser["headimgurl"]);
                $local_file = fopen($filename, 'w');
                if (false !== $local_file) {
                    if (false !== fwrite($local_file, $imgAvatar['body'])) {
                        fclose($local_file);
                    }
                }

                mergeImage($target_file, $filename, $target_file, array('left' => 286, 'top' => 380, 'width' => 108, 'height' => 108));
                $media = $this -> app->material->uploadImage($target_file);
                $this -> user -> poster_media_id = $media['media_id'];
                $this -> user -> poster_expire_time = time() + self::EXPIRETIME;
                $this -> user -> save();
                return new Image($media['media_id']);
            } elseif ($message['EventKey'] == 'BQHD') {

            }

        }
        elseif($event == 'LOCATION'){
            return $this -> locationHandle($message);
        }elseif($event == 'unsubscribe'){
            return $this -> unsubscribe($message);

        }

        return new Text($this -> msg);
    }

    protected function unsubscribe($message){
//        file_put_contents('demo.txt',$this -> user -> openid);
        $this -> user -> is_sub = 0;
        $this -> user -> save();
    }

    /**
     * 关注
     * @param $message
     * @return Text
     */
    protected function subscribe($message){
        $groupId = (!empty($message['EventKey'])) ? str_replace("qrscene_", "", $message['EventKey']) : "0";
        if($groupId){
            $this -> user -> group_id = $groupId;
        }
        $this -> user -> is_sub = 1;
        $this -> user -> save();

        return new Text($this -> msg);
    }

    public static function addUser($username,$extend = []){

        $password = '123456';
        $email = 'aaa@dd.com';
        $mobile = '';
        $ip = request()->ip();
        $time = time();

        $data = [
            'username' => $username,
            'password' => $password,
            'email'    => $email,
            'mobile'   => $mobile,
            'level'    => 1,
            'score'    => 0,
            'avatar'   => $extend['headimgurl'],
        ];
        $params = array_merge($data, [
            'nickname'  => $username,
            'salt'      => Random::alnum(),
            'jointime'  => $time,
            'joinip'    => $ip,
            'logintime' => $time,
            'loginip'   => $ip,
            'prevtime'  => $time,
            'status'    => 'normal'
        ]);
        $params['password'] = md5(md5($password).$params['salt']);
        $params = array_merge($params, $extend);

        Db::startTrans();
        try {
            $user = User::create($params, true);
            Db::commit();
        } catch (Exception $e) {
            Db::rollback();
            return false;
        }
        $user = User::get($user -> id);
        return $user;
    }
}